<template>
  <el-select
    ref="select"
    popper-class="TREE_SELECT_POPPER"
    :value="showLabel"
    :size="size"
    :placeholder="placeholder"
    :clearable="clearable"
    :disabled="disabled"
    :filterable="filterable"
    :filter-method="selectFilter"
    @visible-change="visibleChange"
    @focus="selectFocus"
    @clear="emitVal"
  >
    <el-option
      class="option_li"
      :value="showLabel"
      :label="showLabel"
      :style="{ height: optionHeight + 'px' }"
    >
      <el-scrollbar class="option_li_scroll">
        <el-tree
          ref="tree"
          :accordion="accordion"
          :data="options"
          :props="props"
          :node-key="props.value"
          :show-checkbox="multiple"
          :default-expanded-keys="
            multiple && Array.isArray(value) ? value : [value]
          "
          :default-checked-keys="multiple && Array.isArray(value) ? value : []"
          :expand-on-click-node="false"
          :check-strictly="checkStrictly"
          :filter-node-method="treeFilter"
          @node-click="nodeClick"
          @check="nodeCheck"
        />
      </el-scrollbar>
    </el-option>
  </el-select>
</template>
 

<script>
import pinyinMatch from "pinyin-match";
export default {
  name: "TreeSelect",
  props: {
    props: {
      // 配置项
      type: Object,
      default() {
        return {
          value: "value",
          label: "label",
          children: "children",
        };
      },
    },
    options: {
      // 选项列表数据
      type: Array,
      default() {
        return [];
      },
    },
    value: {
      // 绑定值
      type: [String, Number, Array],
      default: "",
    },
    accordion: {
      // 是否每次只展开一个同级树节点
      type: Boolean,
      default: false,
    },
    size: {
      type: String,
      default: "",
    },
    multiple: {
      // 是否可多选
      type: Boolean,
      default: false,
    },
    filterable: {
      // 是否可搜索
      type: Boolean,
      default: true,
    },
    clearable: {
      // 是否可清空
      type: Boolean,
      default: true,
    },
    disabled: {
      // 是否禁用
      type: Boolean,
      default: false,
    },
    placeholder: {
      type: String,
      default: "",
    },
    checkStrictly: {
      // 父子是否不互相关联
      type: Boolean,
      default: false,
    },
    lastLevel: {
      type: String,
      default: "",
    },
    infoError: {
      type: String,
      default: "",
    },
    popHeight: {
      type: [String, Number],
      default: 247,
    },
  },
  data() {
    return {
      optionHeight: 247,
    };
  },
  computed: {
    showLabel() {
      let label = "";
      const value = this.value;
      if (this.multiple) {
        // 多选
        if (Array.isArray(value) && value.length > 0) {
          const labelArr = [];
          value.forEach((value) => {
            labelArr.push(this.queryTree(this.options, value));
          });
          label = labelArr.join(",");
        }
      } else {
        // 单选
        if (value) {
          label = this.queryTree(this.options, value);
        }
      }
      return label;
    },
  },
  methods: {
    // 搜索树状数据中的 ID,获取label
    queryTree(tree, id) {
      let stark = [];
      stark = stark.concat(tree);
      let label = "";
      while (stark.length) {
        const temp = stark.shift();
        if (temp[this.props.children]) {
          stark = stark.concat(temp[this.props.children]);
        }
        if (temp[this.props.value] === id) {
          label = temp[this.props.label];
        }
      }
      return label;
    },
    // 提交值
    emitVal(val) {
      if (!val) {
        val = this.multiple ? [] : "";
      }
      this.$emit("input", val);
    },
    // select框获得焦点
    selectFocus() {
      this.$refs.tree.filter("");
      this.$emit("on-focus");
    },
    // select option过滤
    selectFilter(label) {
      this.$refs.tree.filter(label);
      return true;
    },
    // 树过滤方法
    treeFilter(query, data) {
      if (!query) {
        return true;
      } else {
        const labelArray = query.split(",");
        // 拼配全有科室 误删
        // return labelArray.some(value => {
        //   return value && data[this.props.label].includes(value)
        // })
        return labelArray.some((value) => {
          return value && pinyinMatch.match(data[this.props.label], value);
        });
      }
    },
    // 下拉框出现/隐藏
    visibleChange(show) {
      if (show) {
        this.$nextTick(() => {
          const tree_H = this.$refs.tree.$el.clientHeight;
          if (tree_H < this.optionHeight) {
            this.optionHeight = this.popHeight;
          }
        });
      }
    },
    // 点击节点
    nodeClick(node) {
      if (!this.multiple) {
        if (node[this.lastLevel] === 0) {
          this.$message.error(this.infoError);
          this.emitVal();
          return false;
        }
        this.emitVal(node[this.props.value]);
        this.$emit("info", node);
        this.$refs.select.blur(); // 使select失去焦点 隐藏下拉框
      }
    },
    // 点击复选框
    nodeCheck(node, data) {
      this.emitVal(data.checkedKeys);
    },
  },
};
</script>
<style lang="scss" type="text/scss">
.TREE_SELECT_POPPER > .el-scrollbar {
  > .el-scrollbar__bar.is-vertical {
    right: 10px;
    display: none;
  }
}
.TREE_SELECT_POPPER .el-select-dropdown__item {
  background: #fff;
}
</style>
<style scoped lang="scss" type="text/scss">
.el-select-dropdown__item {
  height: auto;
  padding: 0;
  &.selected {
    font-weight: normal;
  }
}
.el-tree ::v-deep .el-tree-node__content {
  height: 34px !important;
  padding: 0 10px 0 0;
}
.option_li {
  padding: 0;
  background-color: #fff;
  &.selected {
    font-weight: normal;
  }
  .option_li_scroll {
    height: 100%;
    ::v-deep .el-scrollbar__wrap {
      overflow-x: hidden;
    }
  }
}
.el-tree {
  box-sizing: border-box;
  padding: 0 12px;
}
</style>